package cn.com.twoke.application.game.mario.core.ecs.level;

import cn.com.twoke.application.game.mario.core.ecs.world.GameWorld;
import cn.com.twoke.application.game.mario.game.entity.EntityBuilderFactory;
import cn.com.twoke.application.game.mario.game.scene.SceneManager;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class LevelManagerImpl implements LevelManager {

    private final GameWorld world;
    private final SceneManager sceneManager;
    private final EntityBuilderFactory entityFactory;
    private final Map<String, Level> levels;
    private String currentLevelName = "";

    public LevelManagerImpl(GameWorld world, SceneManager sceneManager) {
        this.world = world;
        this.sceneManager = sceneManager;
        this.entityFactory = new EntityBuilderFactory(world);
        this.levels = new HashMap<>();
    }

    @Override
    public void add(Level level) {
        if (levels.containsKey(level.getName())) {
            log.warn("Level with name {} already exists", level.getName());
            return;
        }
        if (level instanceof AbstractLevel) {
            ((AbstractLevel) level).setLevelManager(this);
            ((AbstractLevel) level).setEntityBuilderFactory(this.entityFactory);
            ((AbstractLevel) level).setSceneManager(this.sceneManager);
        }
        this.levels.put(level.getName(), level);
    }

    @Override
    public Level current() {
        synchronized (this.currentLevelName) {
            return this.levels.get(this.currentLevelName);
        }
    }

    @Override
    public void checkin(String name) {
        // 清除entity
        this.world.getEntities().clear();
        if (this.levels.containsKey(name)) {
            synchronized (this.currentLevelName) {
                this.currentLevelName = name;
                initLevel(this.currentLevelName);
            }
        }
    }


    private void initLevel(String levelName) {
        this.levels.get(levelName).init(world);
    }
}
